/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.merak.core.model.parameter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Pattern;

/**
 * Represents a immutable pair <name,value> where the value is always
 * a string.
 * @author fmarinho */
public class Parameter implements IParameter<String> {

	//~ Attributes ///////////////////////////////////////////////////////////////
	//****************************************************************************
	private String name  = "Undefined";
	private String value = "";

	//~ Constructors /////////////////////////////////////////////////////////////
	//****************************************************************************
	/** @param name The name used to identify the parameter
	 *  @param value The parameter's content */
	public Parameter(String name,String value) {
		this.setName(name);
		this.setValue(value);
	}

	//~ Methods //////////////////////////////////////////////////////////////////
	//****************************************************************************
	@Override
	public String getName() {
		return this.name;
	}
	//****************************************************************************
	@Override
	public String getValue() {
		return this.value;
	}
	//****************************************************************************
	@Override
	public String getUpperCase() {
		return this.value.toUpperCase();
	}
	//****************************************************************************
	@Override
	public String getLowerCase() {
		return this.value.toLowerCase();
	}
	//****************************************************************************
	@Override
	public String getValue(Pattern pattern) {

		// Check if 'value' is valid
		boolean isValid = pattern.matcher(this.value).matches();

		// If not a valid value, send a message to the user
		if ( ! isValid  ) throw new ParameterException(
			"The field '" + this.getName() + "' has invalid format: "+
			" the assigned value was '" + this.value + "'.",
			this
		);

		// It is all right, return the value
		return this.value;

	}
	//****************************************************************************
	@Override
	public long getLong() {

		try {
			return this.isNull() ? 0 : Long.parseLong(this.value);
		}
		catch (NumberFormatException e) {
			throw new ParameterException(
				"The field '" +this.getName()+ "' must contain a long number, " +
				"but the assigned value was '" + this.value + "'.",
				this
			);
		}

	}
	//****************************************************************************
	@Override
	public int getInt() {

		try {
			return this.isNull() ? 0 : Integer.parseInt(this.value);
		}
		catch (NumberFormatException e) {
			throw new ParameterException(
				"The field '"+this.getName()+"' must contain an integer number, " +
				"but assigned value was " +	this.value + ".",
				this
			);
		}

	}
	//****************************************************************************
	@Override
	public double getFloat() {

		try {
			return this.isNull() ? 0 : Float.parseFloat(this.value.replace(',','.'));
		}
		catch (NumberFormatException e) {
			throw new ParameterException(
				"The field '" + this.getName() + "' must contain a real number, " +
				"but assigned value was " +	this.value + ".",
				this
			);
		}

	}
	//****************************************************************************
	@Override
	public double getDouble() {

		try {
			return this.isNull() ? 0 : Double.parseDouble(this.value.replace(',','.'));
		}
		catch (NumberFormatException e) {
			throw new ParameterException(
				"The field '" +this.getName() + "' must contain a real number, " +
				"but assigned value was " +	this.value + ".",
				this
			);
		}

	}
	//****************************************************************************
	@Override
	public Date getDate(String pattern)  {

		try {
			return new SimpleDateFormat(pattern).parse(this.value);
		}
		catch (ParseException e) {
			throw new ParameterException(
				"The field '" +this.getName() +
				"' must contain a date like " + pattern +
				", but assigned value was '" + this.value + "'.",
				this
			);
		}

	}
	//****************************************************************************
	@Override
	public boolean getBoolean() {
		return this.isNull() ? false : Boolean.parseBoolean(this.value);
	}
	//****************************************************************************
	@Override
	public String getEmail() {

		// Check if 'value' is an email
		boolean isValid = Parameters.EMAIL.matcher(this.value).matches();

		// If not a valid email, send a message to the user
		if ( ! isValid  ) throw new ParameterException(
			"The field '" +this.getName() + "' must contain a valid email, " +
			"but assigned value was " +	this.value + ".",
			this
		);

		// It is all right, return the value
		return this.value;

	}
	//****************************************************************************
	@Override
	public String getAlphaNumeric() {

		// Check if 'value' is an email
		boolean isValid = Parameters.ALPHANUM.matcher(this.value).matches();

		// If not a valid email, send a message to the user
		if ( ! isValid  ) throw new ParameterException(
			"The field '" + this.getName() + "' must be alpha-numeric, " +
			"but assigned value was " +	this.value + ".",
			this
		);

		// It is all right, return the value
		return this.value;

	}
	//****************************************************************************
	@Override
	public String getNumeric() {

		// Check if 'value' is an email
		boolean isValid = Parameters.NUMERIC.matcher(this.value).matches();

		// If not a valid email, send a message to the user
		if ( ! isValid  ) throw new ParameterException(
			"The field '" + this.getName() + "' must contain a number, " +
			"but assigned value was " +	this.value + ".",
			this
		);

		// It is all right, return the value
		return this.value;

	}
	//****************************************************************************
	@Override
	public String getAlphabetic() {

		// Check if 'value' is an email
		boolean isValid = Parameters.ALPHA.matcher(this.value).matches();

		// If not a valid email, send a message to the user
		if ( ! isValid  ) throw new ParameterException(
			"The field '" + this.getName() + "' must be alphabetic, " +
			"but assigned value was " +	this.value + ".",
			this
		);

		// It is all right, return the value
		return this.value;

	}
	//****************************************************************************
	@Override
	public String getPersonalName() {

		// Check if 'value' is an email
		boolean isValid = Parameters.PERSONALNAME.matcher(this.value).matches();

		// If not valid, send a message to the user
		if ( ! isValid  ) throw new ParameterException(
			"The field '" + this.getName() + "' must be a personal name, " +
			"but assigned value was " +	this.value + ".",
			this
		);

		// It is all right, return the value
		return this.value;

	}
	//****************************************************************************
	@Override
	public String getBrazilianCPF() {

		// Check if 'value' is an email
		boolean isValid = Parameters.CPF.matcher(this.value).matches();

		// If not valid, send a message to the user
		if ( ! isValid  ) throw new ParameterException(
			"The field '" + this.getName() + "' must be a valid CPF, " +
			"but assigned value was " +	this.value + ".",
			this
		);

		// It is all right, return the value
		return this.value;

	}
	//****************************************************************************
	@Override
	public String getBrazilianCNPJ() {

		// Check if 'value' is an email
		boolean isValid = Parameters.CNPJ.matcher(this.value).matches();

		// If not valid, send a message to the user
		if ( ! isValid  ) throw new ParameterException(
			"The field '" + this.getName() + "' must be a valid CPF, " +
			"but assigned value was " +	this.value + ".",
			this
		);

		// It is all right, return the value
		return this.value;

	}
	//****************************************************************************
	protected void setName(String name) {
		this.name = (name==null) ? "Undefined" : name.trim();
	}
	//****************************************************************************
	protected void setValue(String value) {
		this.value = (value==null) ? "" : value.trim();
	}
	//****************************************************************************
	@Override
	public boolean hasValue(String value) {
		return this.value.equals(value);
	}
	//****************************************************************************
	@Override
	public boolean isFilled() {
		return ! this.value.isEmpty();
	}
	//****************************************************************************
	@Override
	public boolean isNull() {
		return this.value.isEmpty();
	}
	//****************************************************************************
	@Override
	public boolean hasInvalidFormat() {
		return false;
	}
	//****************************************************************************
	@Override
	public String toString() {
		return this.getValue();
	}
	//****************************************************************************

}
